"""
Extension Registry

Central registry for managing GSM extensions with dependency resolution, lifecycle management,
auto-discovery, framework detection, and advanced priority-based conflict resolution.
"""

import threading
import time
from typing import Dict, List, Optional, Set, Any, Union, Tuple
from pathlib import Path
import logging
from .base_extension import BaseExtension
from .auto_discovery import ExtensionAutoDiscovery, DiscoveryStats
from .framework_detector import FrameworkDetector
from .enhanced_dependency_validator import EnhancedDependencyValidator
from .template_system import ExtensionTemplateManager
from .priority_system import PriorityLevel

logger = logging.getLogger(__name__)


class ExtensionRegistry:
    """
    Thread-safe registry for managing GSM extensions with advanced features.
    
    Provides registration, dependency resolution, lifecycle management,
    auto-discovery, framework detection, and priority-based conflict resolution.
    """
    
    _instance = None
    _lock = threading.Lock()
    
    def __new__(cls):
        """Singleton implementation."""
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
                    cls._instance._initialized = False
        return cls._instance
    
    def __init__(self):
        """Initialize the registry."""
        if hasattr(self, '_initialized') and self._initialized:
            return
            
        self._extensions: Dict[str, BaseExtension] = {}
        self._enabled_extensions: Set[str] = set()
        self._extension_order: List[str] = []
        self._dependencies: Dict[str, List[str]] = {}
        self._registry_lock = threading.RLock()
        
        # Phase 2 components - Auto-discovery and enhanced features
        self._auto_discovery = ExtensionAutoDiscovery()
        self._framework_detector = FrameworkDetector()
        self._dependency_validator = EnhancedDependencyValidator()
        self._template_manager = ExtensionTemplateManager()
        self._discovery_cache = {}
        self._last_discovery_time = 0.0
        self._auto_discovery_enabled = True
        
        self._initialized = True
    
    def register(self, extension: BaseExtension, enable: bool = True) -> bool:
        """
        Register an extension with the registry.
        
        Args:
            extension: Extension instance to register
            enable: Whether to enable the extension immediately
            
        Returns:
            True if registration succeeded
        """
        with self._registry_lock:
            name = extension.name
            
            # Check for name conflicts
            if name in self._extensions:
                if self._extensions[name] != extension:
                    logger.warning(f"Extension '{name}' already registered with different instance")
                    return False
                return True
            
            # Validate extension
            validation_errors = self._validate_extension(extension)
            if validation_errors:
                logger.error(f"Extension '{name}' validation failed: {validation_errors}")
                return False
            
            # Register extension
            self._extensions[name] = extension
            self._dependencies[name] = extension.get_dependencies()
            
            if enable:
                success = self.enable(name)
                if not success:
                    # Remove from registry if enable failed
                    del self._extensions[name]
                    del self._dependencies[name]
                    return False
            
            logger.info(f"Registered extension: {name} v{extension.version}")
            return True
    
    def unregister(self, name: str) -> bool:
        """
        Unregister an extension from the registry.
        
        Args:
            name: Name of extension to unregister
            
        Returns:
            True if unregistration succeeded
        """
        with self._registry_lock:
            if name not in self._extensions:
                return False
            
            # Disable first if enabled
            if name in self._enabled_extensions:
                self.disable(name)
            
            # Check for dependents
            dependents = self._get_dependents(name)
            if dependents:
                logger.error(f"Cannot unregister '{name}': required by {dependents}")
                return False
            
            # Clean up extension
            extension = self._extensions[name]
            try:
                extension.cleanup()
            except Exception as e:
                logger.warning(f"Extension '{name}' cleanup failed: {e}")
            
            # Remove from registry
            del self._extensions[name]
            del self._dependencies[name]
            
            logger.info(f"Unregistered extension: {name}")
            return True
    
    def enable(self, name: str) -> bool:
        """
        Enable an extension and its dependencies.
        
        Args:
            name: Name of extension to enable
            
        Returns:
            True if enable succeeded
        """
        with self._registry_lock:
            if name not in self._extensions:
                logger.error(f"Extension '{name}' not registered")
                return False
            
            if name in self._enabled_extensions:
                return True  # Already enabled
            
            # Resolve and enable dependencies first
            deps = self._dependencies.get(name, [])
            for dep in deps:
                if not self.enable(dep):
                    logger.error(f"Failed to enable dependency '{dep}' for '{name}'")
                    return False
            
            # Initialize and enable extension
            extension = self._extensions[name]
            try:
                extension.initialize()
                extension.enable()
                self._enabled_extensions.add(name)
                self._update_extension_order()
                
                logger.info(f"Enabled extension: {name}")
                return True
            except Exception as e:
                logger.error(f"Failed to enable extension '{name}': {e}")
                return False
    
    def disable(self, name: str) -> bool:
        """
        Disable an extension.
        
        Args:
            name: Name of extension to disable
            
        Returns:
            True if disable succeeded
        """
        with self._registry_lock:
            if name not in self._extensions:
                return False
            
            if name not in self._enabled_extensions:
                return True  # Already disabled
            
            # Check for enabled dependents
            enabled_dependents = [dep for dep in self._get_dependents(name) 
                                if dep in self._enabled_extensions]
            if enabled_dependents:
                logger.error(f"Cannot disable '{name}': required by enabled extensions {enabled_dependents}")
                return False
            
            # Disable extension
            extension = self._extensions[name]
            try:
                extension.disable()
                self._enabled_extensions.discard(name)
                self._update_extension_order()
                
                logger.info(f"Disabled extension: {name}")
                return True
            except Exception as e:
                logger.error(f"Failed to disable extension '{name}': {e}")
                return False
    
    def get(self, name: str) -> Optional[BaseExtension]:
        """
        Get an extension by name.
        
        Args:
            name: Extension name
            
        Returns:
            Extension instance or None if not found
        """
        with self._registry_lock:
            return self._extensions.get(name)
    
    def get_enabled(self, name: str) -> Optional[BaseExtension]:
        """
        Get an enabled extension by name.
        
        Args:
            name: Extension name
            
        Returns:
            Extension instance or None if not found or disabled
        """
        with self._registry_lock:
            if name in self._enabled_extensions:
                return self._extensions.get(name)
            return None
    
    def list_all(self) -> Dict[str, BaseExtension]:
        """
        Get all registered extensions.
        
        Returns:
            Dictionary mapping names to extensions
        """
        with self._registry_lock:
            return self._extensions.copy()
    
    def list_enabled(self) -> Dict[str, BaseExtension]:
        """
        Get all enabled extensions.
        
        Returns:
            Dictionary mapping names to enabled extensions
        """
        with self._registry_lock:
            return {name: self._extensions[name] 
                   for name in self._enabled_extensions}
    
    def find_for_config(self, config_path: str) -> Optional[BaseExtension]:
        """
        Find the best extension to handle a configuration file using advanced detection.
        
        Args:
            config_path: Path to configuration file
            
        Returns:
            Best matching enabled extension or None
        """
        with self._registry_lock:
            candidates = []
            
            # Use framework detection engine first
            detection_results = detection_engine.detect_framework(config_path)
            framework_candidates = []
            
            for result in detection_results:
                if result.success and result.extension_name in self._enabled_extensions:
                    framework_candidates.append(result.extension_name)
            
            # Fallback to traditional can_handle_config method
            if not framework_candidates:
                for name in self._extension_order:
                    if name in self._enabled_extensions:
                        extension = self._extensions[name]
                        if extension.can_handle_config(config_path):
                            candidates.append(name)
            else:
                candidates = framework_candidates
            
            if not candidates:
                return None
            
            if len(candidates) == 1:
                return self._extensions[candidates[0]]
            
            # Use priority system for conflict resolution
            try:
                context = {
                    'config_path': config_path,
                    'available_extensions': list(self._enabled_extensions)
                }
                
                resolution = priority_system.resolve_conflicts(candidates, context)
                
                if resolution.selected_extension in self._extensions:
                    selected_ext = self._extensions[resolution.selected_extension]
                    logger.info(f"Selected extension {resolution.selected_extension} for {config_path}: {resolution.explanation}")
                    
                    if resolution.warnings:
                        for warning in resolution.warnings:
                            logger.warning(warning)
                    
                    return selected_ext
                
            except Exception as e:
                logger.error(f"Priority-based resolution failed: {e}")
            
            # Fallback to first candidate
            return self._extensions[candidates[0]]
    
    def get_extension_commands(self) -> Dict[str, Any]:
        """
        Get CLI commands provided by enabled extensions.
        
        Returns:
            Dictionary mapping command names to command objects
        """
        with self._registry_lock:
            commands = {}
            
            # Collect commands from all enabled extensions
            for name in self._enabled_extensions:
                extension = self._extensions[name]
                
                # Check if extension provides commands
                if hasattr(extension, 'get_commands'):
                    try:
                        ext_commands = extension.get_commands()
                        if ext_commands and isinstance(ext_commands, dict):
                            commands.update(ext_commands)
                    except Exception as e:
                        logger.warning(f"Failed to get commands from extension '{name}': {e}")
            
            return commands
    
    def get_info(self) -> Dict[str, Any]:
        """
        Get registry information.
        
        Returns:
            Dictionary with registry statistics
        """
        with self._registry_lock:
            return {
                'total_extensions': len(self._extensions),
                'enabled_extensions': len(self._enabled_extensions),
                'extension_names': list(self._extensions.keys()),
                'enabled_names': list(self._enabled_extensions),
                'dependency_count': sum(len(deps) for deps in self._dependencies.values()),
            }
    
    def clear(self) -> None:
        """Clear all extensions from the registry."""
        with self._registry_lock:
            # Disable all extensions first
            for name in list(self._enabled_extensions):
                self.disable(name)
            
            # Clean up and remove all
            for name, extension in self._extensions.items():
                try:
                    extension.cleanup()
                except Exception as e:
                    logger.warning(f"Extension '{name}' cleanup failed: {e}")
            
            self._extensions.clear()
            self._enabled_extensions.clear()
            self._extension_order.clear()
            self._dependencies.clear()
            
            logger.info("Registry cleared")
    
    def register_from_config(self, config_path: Union[str, Path], enable: bool = True) -> bool:
        """
        Register a config-driven extension from a configuration file.
        
        Args:
            config_path: Path to extension configuration file
            enable: Whether to enable the extension immediately
            
        Returns:
            True if registration succeeded
        """
        from .config_driven_extension import ConfigDrivenExtension
        
        try:
            config_path = Path(config_path)
            
            # Check if this is a valid config-driven extension
            if not ConfigDrivenExtension.can_load_config(config_path):
                logger.error(f"Cannot load config-driven extension from {config_path}")
                return False
            
            # Create and register the extension
            extension = ConfigDrivenExtension.from_config_file(config_path)
            return self.register(extension, enable)
            
        except Exception as e:
            logger.error(f"Failed to register config-driven extension from {config_path}: {e}")
            return False
    
    def discover_config_extensions(self, search_paths: List[Union[str, Path]]) -> Dict[str, bool]:
        """
        Discover and register config-driven extensions from search paths.
        
        Args:
            search_paths: List of directories to search for extension configs
            
        Returns:
            Dictionary mapping extension names to registration success status
        """
        from .config_driven_extension import ConfigDrivenExtension
        from .config_parser import ExtensionConfigParser
        
        parser = ExtensionConfigParser()
        results = {}
        
        for search_path in search_paths:
            search_dir = Path(search_path)
            
            if not search_dir.exists() or not search_dir.is_dir():
                logger.warning(f"Extension search path does not exist or is not a directory: {search_dir}")
                continue
            
            logger.info(f"Searching for config-driven extensions in: {search_dir}")
            
            # Look for extension configuration files
            for config_file in search_dir.rglob('*.yaml'):
                if parser.can_parse(config_file):
                    try:
                        # Try to create extension to validate
                        extension = ConfigDrivenExtension.from_config_file(config_file)
                        name = extension.name
                        
                        # Register if not already registered
                        if name not in self._extensions:
                            success = self.register(extension, enable=True)
                            results[name] = success
                            
                            if success:
                                logger.info(f"Discovered and registered config extension: {name} from {config_file}")
                            else:
                                logger.warning(f"Failed to register discovered extension: {name} from {config_file}")
                        else:
                            logger.debug(f"Extension {name} already registered, skipping {config_file}")
                            results[name] = True
                            
                    except Exception as e:
                        logger.warning(f"Failed to load config extension from {config_file}: {e}")
            
            # Also check for JSON files
            for config_file in search_dir.rglob('*.json'):
                if parser.can_parse(config_file):
                    try:
                        # Try to create extension to validate
                        extension = ConfigDrivenExtension.from_config_file(config_file)
                        name = extension.name
                        
                        # Register if not already registered
                        if name not in self._extensions:
                            success = self.register(extension, enable=True)
                            results[name] = success
                            
                            if success:
                                logger.info(f"Discovered and registered config extension: {name} from {config_file}")
                            else:
                                logger.warning(f"Failed to register discovered extension: {name} from {config_file}")
                        else:
                            logger.debug(f"Extension {name} already registered, skipping {config_file}")
                            results[name] = True
                            
                    except Exception as e:
                        logger.warning(f"Failed to load config extension from {config_file}: {e}")
        
        logger.info(f"Extension discovery completed. Found {len(results)} extensions.")
        return results
    
    def auto_discover_extensions(self, 
                                search_paths: Optional[List[Union[str, Path]]] = None,
                                parallel: bool = True,
                                force_refresh: bool = False) -> Dict[str, Any]:
        """
        Auto-discover extensions using the enhanced discovery system.
        
        Args:
            search_paths: Directories to search (defaults to standard paths)
            parallel: Whether to use parallel discovery
            force_refresh: Force refresh of discovery cache
            
        Returns:
            Dictionary with discovery results and statistics
        """
        import time
        
        if search_paths is None:
            # Use standard plugin paths
            search_paths = [
                Path(__file__).parent.parent.parent.parent / 'plugins',
                Path.cwd() / 'plugins',
                Path.home() / '.gsm' / 'plugins'
            ]
        
        # Check cache
        cache_key = ':'.join(str(p) for p in search_paths)
        current_time = time.time()
        
        if not force_refresh and cache_key in self._discovery_cache:
            cached_result, cache_time = self._discovery_cache[cache_key]
            if current_time - cache_time < 300:  # 5 minute cache
                logger.debug("Using cached auto-discovery results")
                return cached_result
        
        with self._registry_lock:
            logger.info(f"Starting auto-discovery in {len(search_paths)} directories")
            
            # Use auto-discovery system
            discovery_result = self._auto_discovery.discover(
                search_paths,
                use_cache=not force_refresh,
                parallel=parallel
            )
            
            # Register discovered extensions
            registered_count = 0
            failed_count = 0
            
            for extension in discovery_result.discovered_extensions:
                try:
                    # Register framework detection patterns if available
                    if hasattr(extension, 'get_detection_patterns'):
                        patterns = extension.get_detection_patterns()
                        if patterns:
                            detection_engine.register_extension_patterns(extension.name, patterns)
                    
                    # Register priority information
                    if hasattr(extension, 'get_priority_info'):
                        priority_info = extension.get_priority_info()
                        if priority_info:
                            priority_system.register_extension_priority(
                                extension.name,
                                priority_info.get('level', PriorityLevel.NORMAL),
                                **priority_info
                            )
                    
                    # Register extension
                    if self.register(extension, enable=True):
                        registered_count += 1
                    else:
                        failed_count += 1
                        
                except Exception as e:
                    logger.error(f"Failed to register discovered extension {extension.name}: {e}")
                    failed_count += 1
            
            # Prepare result summary
            result = {
                'discovery_time': discovery_result.discovery_time,
                'discovered_extensions': len(discovery_result.discovered_extensions),
                'registered_extensions': registered_count,
                'failed_extensions': len(discovery_result.failed_extensions) + failed_count,
                'skipped_paths': len(discovery_result.skipped_paths),
                'duplicate_names': len(discovery_result.duplicate_names),
                'errors': discovery_result.errors,
                'warnings': discovery_result.warnings,
                'extension_details': {
                    ext.name: {
                        'version': ext.version,
                        'description': ext.description,
                        'frameworks': ext.supported_frameworks,
                        'enabled': ext.name in self._enabled_extensions
                    }
                    for ext in discovery_result.discovered_extensions
                }
            }
            
            # Cache results
            self._discovery_cache[cache_key] = (result, current_time)
            self._last_discovery_time = current_time
            
            logger.info(f"Auto-discovery completed: {registered_count} registered, "
                       f"{failed_count} failed, {len(discovery_result.skipped_paths)} skipped")
            
            return result
    
    def validate_extension_dependencies(self, 
                                      extension_name: Optional[str] = None,
                                      detailed: bool = True) -> Dict[str, Any]:
        """
        Validate dependencies for extensions using enhanced validation.
        
        Args:
            extension_name: Specific extension to validate (all if None)
            detailed: Whether to include detailed validation information
            
        Returns:
            Dictionary with validation results
        """
        with self._registry_lock:
            results = {}
            
            extensions_to_check = [extension_name] if extension_name else list(self._extensions.keys())
            
            for name in extensions_to_check:
                if name not in self._extensions:
                    results[name] = {'error': 'Extension not found'}
                    continue
                
                extension = self._extensions[name]
                
                try:
                    # Create dependency requirements
                    requirements = []
                    
                    # Get framework requirements
                    frameworks = getattr(extension, 'supported_frameworks', [])
                    requirements.extend(create_standard_requirements(frameworks))
                    
                    # Get custom requirements if available
                    if hasattr(extension, 'get_dependency_requirements'):
                        custom_reqs = extension.get_dependency_requirements()
                        if custom_reqs:
                            requirements.extend(custom_reqs)
                    
                    # Validate dependencies
                    validation_result = self._dependency_validator.validate_dependencies(
                        requirements, 
                        extension_name=name,
                        parallel=True
                    )
                    
                    # Format results
                    result_data = {
                        'success': validation_result.success,
                        'satisfied_dependencies': validation_result.satisfied_dependencies,
                        'errors_count': validation_result.errors_count,
                        'warnings_count': validation_result.warnings_count,
                        'validation_time': validation_result.validation_time
                    }
                    
                    if detailed:
                        result_data.update({
                            'issues': [
                                {
                                    'severity': issue.severity,
                                    'component': issue.component,
                                    'message': issue.message,
                                    'suggestion': issue.suggestion
                                }
                                for issue in validation_result.issues
                            ],
                            'version_info': validation_result.version_info,
                            'system_info': validation_result.system_info
                        })
                    
                    results[name] = result_data
                    
                except Exception as e:
                    results[name] = {'error': f'Validation failed: {e}'}
            
            return results
    
    def get_framework_detection_info(self, config_path: Optional[str] = None) -> Dict[str, Any]:
        """
        Get framework detection information.
        
        Args:
            config_path: Optional path to analyze for framework detection
            
        Returns:
            Dictionary with detection information
        """
        info = {
            'registered_extensions': detection_engine.get_extension_info(),
            'detection_results': None
        }
        
        if config_path:
            try:
                detection_results = detection_engine.detect_framework(config_path)
                info['detection_results'] = [
                    {
                        'extension_name': result.extension_name,
                        'confidence': result.confidence,
                        'success': result.success,
                        'matched_patterns': len(result.matched_patterns),
                        'failed_patterns': len(result.failed_patterns),
                        'errors': result.errors
                    }
                    for result in detection_results
                ]
            except Exception as e:
                info['detection_error'] = str(e)
        
        return info
    
    def get_priority_system_info(self) -> Dict[str, Any]:
        """Get information about the priority system."""
        return priority_system.get_system_info()
    
    def configure_extension_priority(self, 
                                   extension_name: str,
                                   priority_level: Union[str, PriorityLevel],
                                   priority_score: int = 0,
                                   **kwargs) -> bool:
        """
        Configure priority for an extension.
        
        Args:
            extension_name: Name of extension
            priority_level: Priority level (string or enum)
            priority_score: Additional priority score
            **kwargs: Additional priority metadata
            
        Returns:
            True if successfully configured
        """
        try:
            if isinstance(priority_level, str):
                priority_level = PriorityLevel[priority_level.upper()]
            
            priority_system.register_extension_priority(
                extension_name,
                priority_level,
                priority_score,
                **kwargs
            )
            
            logger.info(f"Configured priority for extension {extension_name}: {priority_level.name}")
            return True
            
        except Exception as e:
            logger.error(f"Failed to configure priority for {extension_name}: {e}")
            return False
    
    def clear_discovery_cache(self) -> None:
        """Clear the auto-discovery cache."""
        with self._registry_lock:
            self._discovery_cache.clear()
            self._auto_discovery.clear_cache()
            logger.debug("Cleared discovery cache")
    
    def get_enhanced_info(self) -> Dict[str, Any]:
        """
        Get comprehensive information about the registry and Phase 2 features.
        
        Returns:
            Dictionary with detailed registry information
        """
        with self._registry_lock:
            basic_info = self.get_info()
            
            enhanced_info = {
                **basic_info,
                'auto_discovery': {
                    'cache_entries': len(self._discovery_cache),
                    'last_discovery': self._last_discovery_time,
                },
                'framework_detection': self.get_framework_detection_info(),
                'priority_system': self.get_priority_system_info(),
                'dependency_validator': {
                    'cache_size': len(self._dependency_validator._cache),
                    'max_workers': self._dependency_validator.max_workers
                },
                'phase2_features': {
                    'auto_discovery': True,
                    'framework_detection': True,
                    'enhanced_dependencies': True,
                    'template_system': True,
                    'priority_system': True
                }
            }
            
            return enhanced_info
    
    # Phase 2 Methods - Auto-Discovery and Advanced Features
    
    def discover_extensions_enhanced(self, 
                                   plugin_dirs: Union[str, Path, List[Union[str, Path]]],
                                   recursive: bool = True,
                                   include_patterns: Optional[List[str]] = None,
                                   exclude_patterns: Optional[List[str]] = None,
                                   auto_register: bool = True) -> Tuple[List[BaseExtension], DiscoveryStats]:
        """
        Enhanced extension discovery using the Phase 2 auto-discovery system.
        
        Args:
            plugin_dirs: Directory or directories to search
            recursive: Search recursively in subdirectories
            include_patterns: Glob patterns to include
            exclude_patterns: Glob patterns to exclude
            auto_register: Automatically register discovered extensions
            
        Returns:
            Tuple of (discovered extensions, discovery statistics)
        """
        with self._registry_lock:
            logger.info(f"Starting enhanced extension discovery in: {plugin_dirs}")
            
            # Use auto-discovery system
            extensions, stats = self._auto_discovery.discover_extensions(
                plugin_dirs, recursive, include_patterns, exclude_patterns
            )
            
            # Auto-register if requested
            if auto_register:
                registered_count = 0
                for extension in extensions:
                    if extension.name not in self._extensions:
                        if self.register(extension, enable=True):
                            registered_count += 1
                        else:
                            logger.warning(f"Failed to register discovered extension: {extension.name}")
                    else:
                        logger.debug(f"Extension {extension.name} already registered")
                        
                logger.info(f"Auto-registered {registered_count} new extensions")
                
            # Update cache
            self._last_discovery_time = time.time()
            
            return extensions, stats
    
    def find_extension_for_config(self, config_path: Path) -> Optional[BaseExtension]:
        """
        Find the best extension to handle a configuration file using framework detection.
        
        Args:
            config_path: Path to configuration file
            
        Returns:
            Best matching extension or None
        """
        with self._registry_lock:
            # Use framework detector to find compatible extensions
            detection_results = self._framework_detector.detect_framework(config_path)
            
            if not detection_results:
                logger.warning(f"No compatible frameworks detected for: {config_path}")
                return None
                
            # Find registered extensions that match detected frameworks
            for result in detection_results:
                framework_name = result.framework_name
                
                # Look for extension with matching framework
                for extension in self._extensions.values():
                    if hasattr(extension, 'supported_frameworks'):
                        if framework_name in extension.supported_frameworks:
                            logger.info(f"Selected extension '{extension.name}' for config {config_path.name} "
                                      f"(framework: {framework_name}, confidence: {result.confidence:.2f})")
                            return extension
                            
            logger.warning(f"No registered extensions found for detected frameworks: "
                         f"{[r.framework_name for r in detection_results]}")
            return None
            
    def validate_extension_dependencies(self, extension_name: str) -> Dict[str, Any]:
        """
        Validate dependencies for an extension using enhanced dependency validator.
        
        Args:
            extension_name: Name of extension to validate
            
        Returns:
            Validation results with detailed information
        """
        with self._registry_lock:
            if extension_name not in self._extensions:
                return {'error': f"Extension '{extension_name}' not found"}
                
            extension = self._extensions[extension_name]
            
            # Get dependency requirements (if extension supports it)
            if hasattr(extension, 'get_dependency_requirements'):
                requirements = extension.get_dependency_requirements()
                summary = self._dependency_validator.validate_requirements(requirements)
                
                return {
                    'extension': extension_name,
                    'total_requirements': summary.total_requirements,
                    'satisfied': summary.satisfied_requirements,
                    'critical_issues': summary.critical_issues,
                    'warnings': summary.warnings,
                    'overall_status': summary.overall_status,
                    'details': [
                        {
                            'name': r.requirement.name,
                            'type': r.requirement.type.value,
                            'satisfied': r.satisfied,
                            'found_version': r.found_version,
                            'error': r.error_message,
                            'suggestions': r.fix_suggestions
                        }
                        for r in summary.results
                    ]
                }
            else:
                return {
                    'extension': extension_name,
                    'message': 'Extension does not support enhanced dependency validation'
                }
                
    def process_template_config(self, config: Dict[str, Any], 
                              context_vars: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """
        Process configuration using template system.
        
        Args:
            config: Configuration dictionary to process
            context_vars: Additional context variables
            
        Returns:
            Processed configuration with variables substituted
        """
        return self._template_manager.process_extension_config(config, context_vars)
        
    def get_framework_detection_info(self) -> Dict[str, Any]:
        """Get information about the framework detection system."""
        return {
            'supported_frameworks': self._framework_detector.get_supported_frameworks(),
            'detection_rules': len(self._framework_detector.detection_rules),
        }
        
    def get_discovery_stats(self) -> Dict[str, Any]:
        """Get statistics about extension discovery."""
        return {
            'cache_entries': len(self._discovery_cache),
            'last_discovery_time': self._last_discovery_time,
            'auto_discovery_enabled': self._auto_discovery_enabled,
        }
        
    def enable_auto_discovery(self, enabled: bool = True) -> None:
        """Enable or disable auto-discovery features."""
        with self._registry_lock:
            self._auto_discovery_enabled = enabled
            logger.info(f"Auto-discovery {'enabled' if enabled else 'disabled'}")
    
    def _validate_extension(self, extension: BaseExtension) -> List[str]:
        """
        Validate an extension before registration.
        
        Args:
            extension: Extension to validate
            
        Returns:
            List of validation error messages
        """
        errors = []
        
        try:
            # Check required properties
            if not extension.name or not isinstance(extension.name, str):
                errors.append("Extension name must be a non-empty string")
            
            if not extension.version or not isinstance(extension.version, str):
                errors.append("Extension version must be a non-empty string")
            
            # Check abstract methods are implemented
            extension.description
            extension.supported_frameworks
            extension.config_schema
            
            # Validate dependencies
            deps = extension.get_dependencies()
            for dep in deps:
                if dep not in self._extensions:
                    errors.append(f"Dependency '{dep}' not registered")
                elif dep == extension.name:
                    errors.append("Extension cannot depend on itself")
            
            # Check for circular dependencies
            if self._has_circular_dependency(extension.name, deps):
                errors.append("Circular dependency detected")
            
        except (AttributeError, NotImplementedError) as e:
            errors.append(f"Extension implementation incomplete: {e}")
        except Exception as e:
            errors.append(f"Extension validation error: {e}")
        
        return errors
    
    def _get_dependents(self, name: str) -> List[str]:
        """
        Get extensions that depend on the given extension.
        
        Args:
            name: Extension name
            
        Returns:
            List of dependent extension names
        """
        dependents = []
        for ext_name, deps in self._dependencies.items():
            if name in deps:
                dependents.append(ext_name)
        return dependents
    
    def _has_circular_dependency(self, name: str, deps: List[str]) -> bool:
        """
        Check for circular dependencies.
        
        Args:
            name: Extension name
            deps: Extension dependencies
            
        Returns:
            True if circular dependency exists
        """
        visited = set()
        
        def dfs(current: str) -> bool:
            if current == name:
                return True
            if current in visited:
                return False
            
            visited.add(current)
            for dep in self._dependencies.get(current, []):
                if dfs(dep):
                    return True
            
            return False
        
        for dep in deps:
            if dfs(dep):
                return True
        
        return False
    
    def _update_extension_order(self) -> None:
        """Update the extension order based on dependencies (topological sort)."""
        # Simple topological sort
        order = []
        visited = set()
        temp_visited = set()
        
        def visit(name: str) -> bool:
            if name in temp_visited:
                return False  # Cycle detected
            if name in visited:
                return True
            
            temp_visited.add(name)
            
            # Visit dependencies first
            for dep in self._dependencies.get(name, []):
                if dep in self._extensions and not visit(dep):
                    return False
            
            temp_visited.remove(name)
            visited.add(name)
            order.append(name)
            return True
        
        # Visit all extensions
        for name in self._extensions:
            if name not in visited:
                if not visit(name):
                    logger.error("Circular dependency detected in extensions")
                    return
        
        self._extension_order = order
    
    def __len__(self) -> int:
        """Get number of registered extensions."""
        with self._registry_lock:
            return len(self._extensions)
    
    def __contains__(self, name: str) -> bool:
        """Check if extension is registered."""
        with self._registry_lock:
            return name in self._extensions
    
    def __iter__(self):
        """Iterate over registered extensions."""
        with self._registry_lock:
            return iter(self._extensions.values())


# Global registry instance
registry = ExtensionRegistry()